import React, { memo, useEffect, useRef, useState, useCallback } from 'react'
import { useDispatch, useSelector, shallowEqual } from 'react-redux';
import { NavLink } from 'react-router-dom'

import {
  getSongDetailAction,
  changeSequenceAction,
  changeCurrentIndexAndSongAction,
  changeCurrentLyricIndexAction
} from "../store/actionCreator";
import { getSizeImage, formatDate, getPlaySong } from '@/utils/format-utils'

import { Slider } from 'antd';
import {
  PlayerBarWrapper,
  Control,
  PlayInfo,
  Operator
} from "./style";


export default memo(function DAppPlayerBar() {
  // props and state
  const [currentTime, setCurrentTime] = useState(0)
  const [progress, setProgress] = useState(0)
  const [isChanging, setIsChanging] = useState(false)
  const [isPlaying, setIsPlaying] = useState(false)

  // redux hooks
  const { currentSong, sequence, lyricList, currentLyricIndex } = useSelector(state => ({
    currentSong: state.getIn(["player", "currentSong"]),
    sequence: state.getIn(["player", "sequence"]),
    lyricList: state.getIn(["player", "lyricList"]),
    currentLyricIndex: state.getIn(["player", "currentLyricIndex"])
  }), shallowEqual)

  const dispatch = useDispatch()

  // other hooks
  const audioRef = useRef()

  useEffect(() => {
    dispatch(getSongDetailAction(167876))
  }, [dispatch])

  useEffect(() => {
    audioRef.current.src = getPlaySong(currentSong.id)
    audioRef.current.play().then(res => {
      setIsPlaying(true)
    }).catch(err => {
      setIsPlaying(false)
    })
  }, [currentSong])

  // other hander
  const picUrl = (currentSong.al && currentSong.al.picUrl) || ""
  const artist = (currentSong.ar && currentSong.ar[0].name) || ""
  const duration = currentSong.dt || 0
  // 对时间进行格式化
  const showDuration = formatDate(duration, "mm:ss")
  const showCurrentTime = formatDate(currentTime, "mm:ss")


  // handle function
  const changeSequence = () => {
    let currentSequence = sequence + 1
    if (currentSequence > 2) {
      currentSequence = 0
    }
    dispatch(changeSequenceAction(currentSequence))
  }

  const changeMusic = (tag) => {
    dispatch(changeCurrentIndexAndSongAction(tag))
  }

  // 歌曲播放结束后的处理
  const handleMusicEnded = () => {
    if (sequence === 2) { //单曲循环
      audioRef.current.currentTime = 0
      audioRef.current.play()
    } else { // 顺序和随机播放
      dispatch(changeCurrentIndexAndSongAction(1))
    }
  }

  const playMusic = useCallback(() => {
    isPlaying ? audioRef.current.pause() : audioRef.current.play()
    setIsPlaying(!isPlaying)
  }, [isPlaying])

  // 当时间发生改变
  function timeUpdate(e) {
    const currentTime = e.target.currentTime
    if (!isChanging) {
      setCurrentTime(currentTime * 1000)
      setProgress(currentTime * 1000 / duration * 100)
    }

    // 获取当前歌词
    let i = 0
    for (; i < lyricList.length; i++) {
      let lyricItem = lyricList[i]
      if (currentTime * 1000 < lyricItem.time) {
        break;
      }
    }
    // 只需要当前歌词发生改变才dispatch
    if (currentLyricIndex !== i - 1) {
      dispatch(changeCurrentLyricIndexAction(i - 1))
    }
  }

  const sliderChange = useCallback(value => {
    setIsChanging(true)
    setProgress(value)
    const currentTime = value / 100 * duration
    setCurrentTime(currentTime)
  }, [duration])

  const sliderAfterChange = useCallback(value => {
    const currentTime = value / 100 * duration / 1000
    audioRef.current.currentTime = currentTime
    setCurrentTime(currentTime * 1000)
    setIsChanging(false)

    if (!isPlaying) {
      playMusic()
    }
  }, [duration, isPlaying, playMusic])

  return (
    <PlayerBarWrapper className="sprite_playerbar">
      <div className="content wrap-v2">
        <Control isPlaying={isPlaying}>
          <button className="sprite_playerbar prev"
            onClick={e => changeMusic(-1)}></button>
          <button className="sprite_playerbar play"
            title="播放/暂停(p)"
            onClick={e => playMusic()}></button>
          <button className="sprite_playerbar next"
            onClick={e => changeMusic(1)}></button>
        </Control>
        <PlayInfo>
          <div className="image">
            <NavLink href="/todo" to="/discover/player">
              <img src={getSizeImage(picUrl, 35)} alt="" />
            </NavLink>
          </div>
          <div className="info">
            <div className="song">
              <span className="song-name">{currentSong.name}</span>
              <span className="singer-name">{artist}</span>
            </div>
            <div className="progress">
              <Slider value={progress} onChange={sliderChange} onAfterChange={sliderAfterChange} />
              <div className="time">
                <span className="now-time">{showCurrentTime}</span>
                <span className="divider">/</span>
                <span className="duration">{showDuration}</span>
              </div>
            </div>
          </div>
        </PlayInfo>
        <Operator sequence={sequence}>
          <div className="left">
            <button className="btn favor sprite_playerbar"></button>
            <button className="btn share sprite_playerbar"></button>
          </div>
          <div className="right sprite_playerbar">
            <button className="btn volume sprite_playerbar"></button>
            <button className="btn loop sprite_playerbar"
              onClick={e => changeSequence()}></button>
            <button className="btn playlist sprite_playerbar"></button>
          </div>
        </Operator>
      </div>
      <audio ref={audioRef}
        onTimeUpdate={e => timeUpdate(e)}
        onEnded={e => handleMusicEnded()} />
    </PlayerBarWrapper>
  )
})
